<i18n locale="zh-CN" lang="yaml">
Add Script Market  : 添加脚本市场
Setup Script Market: 配置脚本市场

Branch: 分支
Region: 地域

Password here is always required when the Script Market requires password : 如脚本市场需要密码，则每次修改都必须重新输入密码
AK Secret here is always required when the Script Market requires password: 如脚本市场需要 AK Secret，则每次修改都必须重新输入 AK Secret

Please input Script Market type        : 请输入脚本市场类型
Please input URL                       : 请输入 URL
Please input Branch                    : 请输入分支
Please input user                      : 请输入用户名
Please input password                  : 请输入密码
Please input endpoint                  : 请输入访问地址
Please input bucket                    : 请输入 Bucket
Please input folder                    : 请输入文件夹
Please input AK Id                     : 请输入 AK ID
Please input AK Secret                 : 请输入 AK Secret
'Should start with http:// or https://': '必须以 http:// 或 https:// 开头'
Manage this Script Market              : 管理此脚本市场

Script Market added  : 脚本市场已添加
Script Market saved  : 脚本市场已保存
Script Market removed: 脚本市场已删除

Are you sure you want to delete the Script Market?: 是否确认删除此脚本市场？
</i18n>

<!-- Generated by OpenCC START -->
<i18n locale="zh-HK" lang="yaml">
AK Secret here is always required when the Script Market requires password: 如腳本市場需要 AK Secret，則每次修改都必須重新輸入 AK Secret
Add Script Market: 添加腳本市場
Are you sure you want to delete the Script Market?: 是否確認刪除此腳本市場？
Branch: 分支
Manage this Script Market: 管理此腳本市場
Password here is always required when the Script Market requires password: 如腳本市場需要密碼，則每次修改都必須重新輸入密碼
Please input AK Id: 請輸入 AK ID
Please input AK Secret: 請輸入 AK Secret
Please input Branch: 請輸入分支
Please input Script Market type: 請輸入腳本市場類型
Please input URL: 請輸入 URL
Please input bucket: 請輸入 Bucket
Please input endpoint: 請輸入訪問地址
Please input folder: 請輸入文件夾
Please input password: 請輸入密碼
Please input user: 請輸入用户名
Region: 地域
Script Market added: 腳本市場已添加
Script Market removed: 腳本市場已刪除
Script Market saved: 腳本市場已保存
Setup Script Market: 配置腳本市場
Should start with http:// or https://: 必須以 http:// 或 https:// 開頭
</i18n>
<i18n locale="zh-TW" lang="yaml">
AK Secret here is always required when the Script Market requires password: 如指令碼市場需要 AK Secret，則每次修改都必須重新輸入 AK Secret
Add Script Market: 新增指令碼市場
Are you sure you want to delete the Script Market?: 是否確認刪除此指令碼市場？
Branch: 分支
Manage this Script Market: 管理此指令碼市場
Password here is always required when the Script Market requires password: 如指令碼市場需要密碼，則每次修改都必須重新輸入密碼
Please input AK Id: 請輸入 AK ID
Please input AK Secret: 請輸入 AK Secret
Please input Branch: 請輸入分支
Please input Script Market type: 請輸入指令碼市場型別
Please input URL: 請輸入 URL
Please input bucket: 請輸入 Bucket
Please input endpoint: 請輸入訪問地址
Please input folder: 請輸入資料夾
Please input password: 請輸入密碼
Please input user: 請輸入使用者名稱
Region: 地域
Script Market added: 指令碼市場已新增
Script Market removed: 指令碼市場已刪除
Script Market saved: 指令碼市場已儲存
Setup Script Market: 配置指令碼市場
Should start with http:// or https://: 必須以 http:// 或 https:// 開頭
</i18n>
<!-- Generated by OpenCC END -->

<template>
  <el-dialog
    id="ScriptSetSetup"
    :visible.sync="show"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    width="750px">

    <template slot="title">
      {{ pageTitle }} <code class="text-main" v-if="pageMode === 'setup'">{{ data.title || C.SCRIPT_MARKET_TYPE_MAP.get(selectedType).name }}</code>
    </template>

    <el-container direction="vertical">
      <el-main>
        <div class="setup-form">
          <el-form ref="form" label-width="135px" :model="form" :rules="formRules">
            <!-- Fake user/password -->
            <el-form-item style="height: 0; overflow: hidden">
              <input tabindex="-1" type="text" name="username" />
              <input tabindex="-1" type="password" name="password" />
            </el-form-item>

            <el-form-item :label="$t('Type')" prop="type" v-if="pageMode === 'add'">
              <el-select v-model="form.type" @change="switchType">
                <el-option v-for="opt in C.SCRIPT_MARKET_TYPE" :label="opt.name" :key="opt.key" :value="opt.key"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item :label="$t('Type')" v-else>
              <el-select v-model="selectedType" :disabled="true">
                <el-option :label="C.SCRIPT_MARKET_TYPE_MAP.get(selectedType).name" :value="selectedType"></el-option>
              </el-select>
            </el-form-item>

            <template v-if="selectedType">
              <el-form-item v-if="C.SCRIPT_MARKET_TYPE_MAP.get(selectedType).logo">
                <el-image class="script-market-logo" :class="`logo-${form.type}`" :src="common.getScriptMarketLogo(form)"></el-image>
              </el-form-item>

              <el-form-item>
                <InfoBlock type="warning" :title="C.SCRIPT_MARKET_TYPE_MAP.get(selectedType).tip" />
              </el-form-item>

              <el-form-item :label="$t('Title')">
                <el-input :placeholder="$t('Optional')"
                  maxlength="200"
                  v-model="form.title"></el-input>
              </el-form-item>

              <el-form-item :label="$t('Description')">
                <el-input :placeholder="$t('Optional')"
                  type="textarea"
                  resize="none"
                  :autosize="{minRows: 2}"
                  maxlength="5000"
                  v-model="form.description"></el-input>
              </el-form-item>

              <!-- Changable area -->
              <el-form-item label="URL" v-if="hasConfigField(selectedType, 'url')" prop="configJSON.url">
                <el-input
                  type="textarea"
                  resize="none"
                  :autosize="{minRows: 2}"
                  maxlength="5000"
                  v-model="form.configJSON.url"></el-input>
              </el-form-item>

              <el-form-item :label="$t('Branch')" v-if="hasConfigField(selectedType, 'branch')" prop="configJSON.branch">
                <el-input placeholder="master"
                  v-model="form.configJSON.branch"></el-input>
              </el-form-item>

              <el-form-item :label="$t('User')" v-if="hasConfigField(selectedType, 'user')" prop="configJSON.user">
                <el-input
                  v-model="form.configJSON.user"></el-input>
              </el-form-item>

              <el-form-item :label="$t('Password')" v-if="hasConfigField(selectedType, 'password')" prop="configJSON.password">
                <el-input
                  v-model="form.configJSON.password" show-password></el-input>
                <InfoBlock v-if="pageMode === 'setup'" type="info" :title="$t('Password here is always required when the Script Market requires password')" />
              </el-form-item>

              <el-form-item :label="$t('Endpoint')" v-if="hasConfigField(selectedType, 'endpoint')" prop="configJSON.endpoint">
                <el-input
                  v-model="form.configJSON.endpoint"></el-input>
              </el-form-item>

              <el-form-item label="Bucket" v-if="hasConfigField(selectedType, 'bucket')" prop="configJSON.bucket">
                <el-input
                  v-model="form.configJSON.bucket"></el-input>
              </el-form-item>

              <el-form-item :label="$t('Folder')" v-if="hasConfigField(selectedType, 'folder')" prop="configJSON.folder">
                <el-input
                  v-model="form.configJSON.folder"></el-input>
              </el-form-item>

              <el-form-item label="AK ID" v-if="hasConfigField(selectedType, 'accessKeyId')" prop="configJSON.accessKeyId">
                <el-input
                  v-model="form.configJSON.accessKeyId"></el-input>
              </el-form-item>

              <el-form-item label="AK Secret" v-if="hasConfigField(selectedType, 'accessKeySecret')" prop="configJSON.accessKeySecret">
                <el-input
                  v-model="form.configJSON.accessKeySecret" show-password></el-input>
                <InfoBlock v-if="pageMode === 'setup'" type="info" :title="$t('AK Secret here is always required when the Script Market requires password')" />
              </el-form-item>

              <el-form-item v-if="pageMode === 'add' && !C.SCRIPT_MARKET_TYPE_MAP.get(selectedType).isReadonly">
                <el-switch
                  v-model="setAdmin"
                  :active-text="$t('Manage this Script Market')">
                </el-switch>
              </el-form-item>

              <el-form-item v-if="pageMode === 'setup' && data.isAdmin">
                <div class="manage-this-script-market-tip">
                  <i class="fa fa-fw fa-check text-main fa-2x"></i>
                  <span>{{ $t('Manage this Script Market') }}</span>
                </div>
              </el-form-item>
              <!-- End of changable area -->

              <el-form-item class="setup-footer">
                <el-link type="danger" class="float-left" v-if="pageMode === 'setup'" @click="deleteData">{{ $t('Delete') }}</el-link>
                <el-button type="primary" @click="submitData"
                  :disabled="isSaving">
                  <i class="fa fa-fw fa-circle-o-notch fa-spin" v-if="isSaving"></i>
                  {{ $t('Save') }}
                </el-button>
              </el-form-item>
            </template>
          </el-form>
        </div>
      </el-main>
    </el-container>
  </el-dialog>
</template>

<script>
export default {
  name: 'ScriptMarketSetup',
  components: {
  },
  watch: {
    show(val) {
      if (val && this.$refs.form) {
        this.$refs.form.clearValidate();
      }

      if (!val) {
        this.$root.$emit('reload.scriptMarketList');
      }
    },
  },
  methods: {
    updateValidator(type) {
      if (this.$refs.form) this.$refs.form.clearValidate();

      let fieldMap = this.C.SCRIPT_MARKET_TYPE_MAP.get(type).configFields;
      if (!fieldMap) return;

      for (let f in fieldMap) if (fieldMap.hasOwnProperty(f)) {
        let opt = fieldMap[f];
        if (!opt) continue;

        let rule = this.formRules[`configJSON.${f}`];
        if (rule) {

          if (type === 'git' && [ 'user', 'password' ].indexOf(f) >= 0) {
            // The user, password of the git repo requires special handling.
            rule[0].required = this.isUserPasswordRequired;
          } else {
            rule[0].required = !!opt.isRequired;
          }
        }
      }
    },
    fillDefault(type) {
      let fieldMap = this.C.SCRIPT_MARKET_TYPE_MAP.get(type).configFields;
      if (!fieldMap) return;

      let nextConfigJSON = {};
      for (let f in fieldMap) if (fieldMap.hasOwnProperty(f)) {
        let opt = fieldMap[f];
        if (!opt) continue;

        if (this.T.notNothing(opt.default)) {
          nextConfigJSON[f] = opt.default;
        }
      }

      this.form.configJSON = nextConfigJSON;
    },
    switchType(type) {
      this.setAdmin = false;
      this.fillDefault(type);
      this.updateValidator(type);
    },
    async loadData(id) {
      if (!id) {
        this.pageMode = 'add';
        this.T.jsonClear(this.form);
        this.form.configJSON = {};
        this.data = {};

      } else {
        this.pageMode = 'setup';
        this.data.id = id;

        let apiRes = await this.T.callAPI_getOne('/api/v1/script-markets/do/list', this.data.id);
        if (!apiRes || !apiRes.ok) return;

        this.data = apiRes.data;

        let nextForm = {};
        Object.keys(this.form).forEach(f => nextForm[f] = this.data[f]);
        this.form = nextForm;

        this.updateValidator(this.data.type);
      }

      this.show = true;
    },
    async submitData() {
      try {
        await this.$refs.form.validate();
      } catch(err) {
        return console.error(err);
      }

      this.isSaving = true;

      let wait = this.T.createWaitLoading();

      switch(this.pageMode) {
        case 'add':
          await this.addData();
          break;

        case 'setup':
          await this.modifyData();
          break;
      }

      wait.end(() => { this.isSaving = false });
    },
    _getFormData() {
      let _formData = this.T.jsonCopy(this.form);
      if (_formData.configJSON) {
        for (let k in _formData.configJSON) {
          if (this.T.isNothing(_formData.configJSON[k])) {
            _formData.configJSON[k] = null;
          }
        }
      }
      return _formData;
    },
    async addData() {
      if (this.form.type === 'git'
        && this.setAdmin
        && !this.$root.checkUserProfileForGit()) return;

      let _formData = this._getFormData();

      let apiRes = await this.T.callAPI('post', '/api/v1/script-markets/do/add', {
        body    : { data: _formData, setAdmin: this.setAdmin },
        feedback: { okMessage: this.$t('Script Market added') },
      });
      if (!apiRes || !apiRes.ok) return;

      this.$store.commit('updateHighlightedTableDataId', apiRes.data.id);
      this.show = false;
    },
    async modifyData() {
      if (this.data.type === 'git'
        && this.data.isAdmin
        && !this.$root.checkUserProfileForGit()) return;

      let _formData = this._getFormData();
      delete _formData.id;
      delete _formData.type;

      let apiRes = await this.T.callAPI('post', '/api/v1/script-markets/:id/do/modify', {
        params  : { id: this.data.id },
        body    : { data: _formData },
        feedback: { okMessage: this.$t('Script Market saved') },
      });
      if (!apiRes || !apiRes.ok) return;

      this.$store.commit('updateHighlightedTableDataId', apiRes.data.id);
      this.show = false;
    },
    async deleteData() {
      if (this.data.type === 'git'
        && this.data.isAdmin
        && !this.$root.checkUserProfileForGit()) return;

      if (!await this.T.confirm(this.$t('Are you sure you want to delete the Script Market?'))) return;

      let apiRes = await this.T.callAPI('/api/v1/script-markets/:id/do/delete', {
        params  : { id: this.data.id },
        feedback: { okMessage: this.$t('Script Market removed') },
      });
      if (!apiRes || !apiRes.ok) return;

      this.show = false;
    },
    hasConfigField(type, field) {
      if (!this.C.SCRIPT_MARKET_TYPE_MAP.get(type) || !this.C.SCRIPT_MARKET_TYPE_MAP.get(type).configFields) {
        return false;
      }
      return (field in this.C.SCRIPT_MARKET_TYPE_MAP.get(type).configFields);
    },
  },
  computed: {
    isUserPasswordRequired() {
      let configJSON = this.pageMode === 'setup'
                    ? this.data.configJSON
                    : this.form.configJSON;
      configJSON = configJSON || {};
      return !!(configJSON.user || configJSON.password) || this.setAdmin;
    },
    pageTitle() {
      const _map = {
        setup: this.$t('Setup Script Market'),
        add  : this.$t('Add Script Market'),
      };
      return _map[this.pageMode];
    },
    selectedType() {
      switch(this.pageMode) {
        case 'add':
          return this.form.type;

        case 'setup':
          return this.data.type;
      }
    },
  },
  props: {
  },
  data() {
    return {
      show    : false,
      pageMode: null,

      data: {},

      setAdmin: false,

      form: {
        name       : null,
        type       : null,
        description: null,
        configJSON : {},
      },
      formRules: {
        type: [
          {
            trigger : 'blur',
            message : this.$t('Please input Script Market type'),
            required: true,
          },
        ],
        'configJSON.url': [
          {
            trigger : 'blur',
            message : this.$t('Please input URL'),
            required: false,
          },
          {
            trigger: 'change',
            message: this.$t('Should start with http:// or https://'),
            pattern: this.C.RE_PATTERN.httpURL,
          },
        ],
        'configJSON.branch': [
          {
            trigger : 'blur',
            message : this.$t('Please input Branch'),
            required: false,
          },
        ],
        'configJSON.user': [
          {
            trigger : 'blur',
            message : this.$t('Please input user'),
            required: this.isUserPasswordRequired,
          },
        ],
        'configJSON.password': [
          {
            trigger : 'blur',
            message : this.$t('Please input password'),
            required: this.isUserPasswordRequired,
          },
        ],
        'configJSON.endpoint': [
          {
            trigger : 'blur',
            message : this.$t('Please input endpoint'),
            required: true,
          },
          {
            trigger: 'change',
            message: this.$t('Should start with http:// or https://'),
            pattern: this.C.RE_PATTERN.httpURL,
          },
        ],
        'configJSON.bucket': [
          {
            trigger : 'blur',
            message : this.$t('Please input bucket'),
            required: true,
          },
        ],
        'configJSON.folder': [
          {
            trigger : 'blur',
            message : this.$t('Please input folder'),
            required: true,
          },
        ],
        'configJSON.accessKeyId': [
          {
            trigger : 'blur',
            message : this.$t('Please input AK Id'),
            required: true,
          },
        ],
        'configJSON.accessKeySecret': [
          {
            trigger : 'blur',
            message : this.$t('Please input AK Secret'),
            required: true,
          },
        ],
      },

      isSaving: false,
    }
  },
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.manage-this-script-market-tip {
  display: flex;
  align-items: center;
}
.manage-this-script-market-tip > * {
  margin-right: 10px;
}
</style>
<style>
.script-market-logo img {
  width: auto;
}
.script-market-logo.logo-git {
  height: 60px !important;
}
.script-market-logo.logo-aliyunOSS {
  height: 80px !important;
}
.script-market-logo.logo-httpService {
  height: 70px !important;
}
</style>
